package cn.com.dcsgo.exception;

import cn.com.dcsgo.utils.ResponseResult;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.io.PrintWriter;
import java.io.Serializable;

/**
 * Sentinel 自定义 BlockException 处理
 * 通常用作 Web 资源触发保护规则后的处理
 * 实现 BlockExceptionHandler 接口，重写 handle 方法
 * 装配到IoC即可
 *
 * @author Dcsgo
 * @since 2025/3/16 10:29
 */
@Component
@RequiredArgsConstructor
public class MyBlockExceptionHandler implements BlockExceptionHandler {
    private final ObjectMapper objectMapper;

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, String s, BlockException e) throws Exception {
        response.setContentType("application/json;charset=utf-8");
        response.setStatus(429);//设置状态码 (Too Many Requests) API Post 便于统计
        PrintWriter writer = response.getWriter();
        String failMsg = "请求被限流了" + e.getClass() + " : " + e.getMessage();
        ResponseResult<Serializable> result = ResponseResult.fail(failMsg);
        String json = objectMapper.writeValueAsString(result);
        writer.write(json);
        writer.flush();
        writer.close();
    }
}
